package cn.demoncat.util.pay.yeepay.config;

import cn.demoncat.util.lang.CollectionUtil;
import cn.demoncat.util.lang.ParamEmptyUtil;
import cn.demoncat.util.pay.config.PayProperties;
import com.yeepay.g3.sdk.yop.client.YopConstants;
import com.yeepay.g3.sdk.yop.config.*;
import com.yeepay.g3.sdk.yop.config.enums.ModeEnum;
import com.yeepay.g3.sdk.yop.config.provider.BaseFixedAppSdkConfigProvider;
import com.yeepay.g3.sdk.yop.encrypt.CertTypeEnum;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.List;

/**
 * 易宝支付配置
 *
 * @author 延晓磊
 * @since 2020年10月14日
 */
@Configuration
public class YeepayConfig {

    @Resource
    private YeepayProperties yeepayProperties;
    @Resource
    private PayProperties payProperties;

    /**
     * 易宝RSA公钥
     */
    private static final String YEEPAY_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6p0XWjscY+gsyqKRhw9MeLsEmhFdBRhT2emOck/F1Omw38ZWhJxh9kDfs5HzFJMrVozgU+SJFDONxs8UB0wMILKRmqfLcfClG9MyCNuJkkfm0HFQv1hRGdOvZPXj3Bckuwa7FrEXBRYUhK7vJ40afumspthmse6bs6mZxNn/mALZ2X07uznOrrc2rk41Y2HftduxZw6T4EmtWuN2x4CZ8gwSyPAW5ZzZJLQ6tZDojBK4GZTAGhnn3bg5bBsBlw2+FLkCQBuDsJVsFPiGh/b6K/+zGTvWyUcu+LUj2MejYQELDO3i2vQXVDk7lVi2/TcUYefvIcssnzsfCfjaorxsuwIDAQAB";

    /**
     * 初始化配置
     * 
     * @author 延晓磊
     * @since 2020年10月14日
     */
    @PostConstruct
    private void init(){
        // 配置DNS缓存，防止易宝URL映射的IP变更
        System.setProperty("sun.net.inetaddr.ttl", "180");
        System.setProperty("sun.net.inetaddr.negative.ttl", "10");
        // 注册配置
        AppSdkConfigProviderRegistry.registerCustomProvider(new BaseFixedAppSdkConfigProvider() {
            @Override
            protected List<SDKConfig> loadCustomSdkConfig() {
             return CollectionUtil.toList(newConfig(yeepayProperties.getAppKey(), yeepayProperties.getRsaPassword(), payProperties.getStatus()));
            }
        });
    }



    /**
     * 创建配置
     *
     * @param appKey        应用ID
     * @param isvPrivateKey RSA私钥：请求接口使用
     * @param status        是否为生产环境
     * @return
     *
     * @author 延晓磊
     * @since 2020年10月15日
     */
    private static SDKConfig newConfig(String appKey, String isvPrivateKey, boolean status){
        ParamEmptyUtil.assertBlank("易宝支付app-key和rsa-password配置不能为空", appKey, isvPrivateKey);
        SDKConfig config = new SDKConfig();
        // 应用ID
        config.setAppKey(appKey);
        // AES密钥（废弃）
        config.setAesSecretKey(null);
        // 同步API请求地址
        config.setServerRoot(YopConstants.DEFAULT_SERVER_ROOT);
        config.setYosServerRoot(YopConstants.DEFAULT_YOS_SERVER_ROOT);
        // 沙箱请求地址
        config.setSandboxServerRoot(YopConstants.DEFAULT_SANDBOX_SERVER_ROOT);
        // 平台公钥
        config.setYopPublicKey(newPubCert());
        // ISV私钥，同于 new YopRequest(appKey, isvPrivateKey)
        config.setIsvPrivateKey(newPriCert(isvPrivateKey));
        // HTTP配置
        config.setHttpClient(newHttpCfg());
        // 默认配置
        config.setDefaulted(true);
        // 生产/沙箱
        config.setMode(status ? ModeEnum.prod : ModeEnum.sandbox);
        return config;
    }

    /**
     * 创建YOP平台公钥
     *
     * @return
     *
     * @author 延晓磊
     * @since 2020年10月15日
     */
    private static CertConfig[] newPubCert(){
        CertConfig config = new CertConfig();
        config.setCertType(CertTypeEnum.RSA2048);
        config.setStoreType(CertStoreType.STRING);
        config.setValue(YEEPAY_PUBLIC_KEY);
        return new CertConfig[]{config};
    }

    /**
     * 创建ISV私钥
     *
     * @param password 密钥文本
     *
     * @return
     *
     * @author 延晓磊
     * @since 2020年10月15日
     */
    private static CertConfig[] newPriCert(String password){
        CertConfig config = new CertConfig();
        config.setCertType(CertTypeEnum.RSA2048);
        config.setStoreType(CertStoreType.STRING);
        config.setValue(password);
        return new CertConfig[]{config};
    }

    /**
     * 创建HTTP配置
     *
     * @return
     *
     * @author 延晓磊
     * @since 2020年10月15日
     */
    private static HttpClientConfig newHttpCfg(){
        HttpClientConfig config = new HttpClientConfig();
        config.setConnectTimeout(30000);
        config.setReadTimeout(30000);
        config.setMaxConnTotal(200);
        config.setMaxConnPerRoute(100);
        return config;
    }

    /**
     * 获取平台私钥
     *
     * InternalConfig.getISVPrivateKey(CertTypeEnum.RSA2048)
     *
     * @return
     *
     * @author 延晓磊
     * @since 2020年10月20日
     */
    private PrivateKey getPrivateKey() {
        try {
            return KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(Base64.getDecoder().decode(yeepayProperties.getRsaPassword())));
        } catch (Exception e) {
            throw new RuntimeException("加载易宝支付私钥失败");
        }
    }

    /**
     * 获取易宝公钥
     *
     * InternalConfig.getYopPublicKey(CertTypeEnum.RSA2048)
     *
     * @return
     *
     * @author 延晓磊
     * @since 2020年10月20日
     */
    private PublicKey getPublicKey() {
        try {
            return KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(Base64.getDecoder().decode(YEEPAY_PUBLIC_KEY)));
        } catch (Exception e) {
            throw new RuntimeException("加载易宝支付公钥失败");
        }
    }
}
